﻿//ChartArea.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Xaml
{
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Linq;

	using Ecng.Collections;
	using Ecng.Serialization;

	/// <summary>
	/// Область графика.
	/// </summary>
	[DisplayName("Область графика")]
	public class ChartArea : ChartPart<ChartArea>
	{
		private sealed class ChartElementCollection : BaseList<IChartElement>
		{
		}

		/// <summary>
		/// Создать <see cref="ChartArea"/>.
		/// </summary>
		public ChartArea()
		{
			Elements = new ChartElementCollection();

			Height = 100;
			IsAligned = true;
		}

		private string _title;

		/// <summary>
		/// Название области графика.
		/// </summary>
		[DisplayName("Название")]
		[Description("Название области графика.")]
		[Category("Основное")]
		public string Title
		{
			get { return _title; }
			set
			{
				_title = value;
				RaisePropertyChanged("Title");
			}
		}

		private bool _axisValuesPosition;

		/// <summary>
		/// Расположить значения оси справа.
		/// </summary>
		[DisplayName("Значения оси справа")]
		[Description("Расположить значения оси справа.")]
		[Category("Основное")]
		public bool AxisValuesPosition
		{
			// True - справа (по умолчанию)
			// False - слева
			get { return _axisValuesPosition; }
			set
			{
				_axisValuesPosition = value;
				RaisePropertyChanged("AxisValuesPosition");
			}
		}

		/// <summary>
		/// Высота области.
		/// </summary>
		[Browsable(false)]
		public float Height { get; set; }

		private bool _isAligned;

		/// <summary>
		/// Связана ли область с другими на графике.
		/// </summary>
		[DisplayName("Связанность")]
		[Description("Связана ли область с другими на графике.")]
		[Category("Основное")]
		public bool IsAligned
		{
			get { return _isAligned; }
			set
			{
				_isAligned = value;
				RaisePropertyChanged("IsAligned");
			}
		}

		/// <summary>
		/// Элементы области (<see cref="ChartIndicatorElement"/>, <see cref="ChartCandleElement"/> и т.д.).
		/// </summary>
		[Browsable(false)]
		public INotifyList<IChartElement> Elements { get; private set; }

		/// <summary>
		/// Загрузить настройки.
		/// </summary>
		/// <param name="storage">Хранилище настроек.</param>
		public override void Load(SettingsStorage storage)
		{
			base.Load(storage);

			Title = storage.GetValue<string>("Title");
			AxisValuesPosition = storage.GetValue("AxisValuesPosition", true);
			Height = storage.GetValue<float>("Height");
			IsAligned = storage.GetValue("IsAligned", true);

			LoadElements<ChartCandleElement>(storage, "Candles");
			LoadElements<ChartIndicatorElement>(storage, "Indicators");
			LoadElements<ChartTradeElement>(storage, "Trades");
			LoadElements<ChartOrderElement>(storage, "Orders");
		}

		/// <summary>
		/// Сохранить настройки.
		/// </summary>
		/// <param name="storage">Хранилище настроек.</param>
		public override void Save(SettingsStorage storage)
		{
			base.Save(storage);

			storage.SetValue("Title", Title);
			storage.SetValue("AxisValuesPosition", AxisValuesPosition);
			storage.SetValue("Height", Height);
			storage.SetValue("IsAligned", IsAligned);

			SaveElements<ChartCandleElement>(storage, "Candles");
			SaveElements<ChartIndicatorElement>(storage, "Indicators");
			SaveElements<ChartTradeElement>(storage, "Trades");
			SaveElements<ChartOrderElement>(storage, "Orders");
		}

		private void LoadElements<T>(SettingsStorage storage, string key)
			where T : ChartElement<T>, new()
		{
			Elements.AddRange(storage.GetValue<IEnumerable<SettingsStorage>>(key).Select(s => s.Load<T>()));
		}

		private void SaveElements<T>(SettingsStorage storage, string key)
			where T : ChartElement<T>
		{
			storage.SetValue(key, Elements.OfType<T>().Select(c => c.Save()).ToArray());
		}

		/// <summary>
		/// Создать копию элемента.
		/// </summary>
		/// <returns>Копия.</returns>
		public override ChartArea Clone()
		{
			var clone = FillClone(new ChartArea
			{
				Title = Title,
				AxisValuesPosition = AxisValuesPosition,
				Height = Height,
			});

			clone.Elements.AddRange(Elements.Select(i => i.Clone()));

			return clone;
		}

		/// <summary>
		/// Получить строковое представление.
		/// </summary>
		/// <returns>Строковое представление.</returns>
		public override string ToString()
		{
			return Title;
		}
	}
}